package org.example.y24.m12;

public class SORMethod {

    private static final double tol = 1e-5;
    private static final double omega = 1.15;
    private static final int N = 100;

    private static void print(double[] x) {
        System.out.println("Solution:");
        for (int i = 0; i < x.length; ++i) {
            System.out.println("x[" + i + "] = " + x[i]);
        }
    }

    private static boolean sor(double[][] A, double[] b, double[] x) {
        int iter = 0;
        double error = 1.0;

        while (error > tol && iter < N) {
            error = 0.0;
            for (int i = 0; i < A.length; ++i) {
                double sum = 0.0;
                for (int j = 0; j < A[0].length; ++j) {
                    if (i != j) {
                        sum += A[i][j] * x[j];
                    }
                }
                double oldX = x[i];
                x[i] = (1 - omega) * x[i] + omega * (b[i] - sum) / A[i][i];
                error += Math.abs(x[i] - oldX);
            }
            iter++;
        }

        if (iter == N) {
            System.out.println("在不收敛的情况下达到的最大迭代次数。");
            return false;
        }

        return true;
    }

    public static void main(String[] args) {
        double[][] A = {
                {5, 1, -1, -2},
                {2, 8, 1, 3},
                {1, -2, -4, -1},
                {-1, 3, 2, 7}
        };
        double[] b = {-2, -6, 6, 12};
        double[] x = new double[A.length];

        if (sor(A, b, x)) {
            print(x);
        } else {
            System.out.println("SOR方法不收敛。");
        }
    }
}
